\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mdel\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mNameError\u001b[0m: name 'x' is not defined"
]
}
],
"source": [
"del x, y\n",
"x, y"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Identifiers"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"*Identifiers* such as variable names are case sensitive and follow certain rules."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**What is the syntax for variable names?**"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"1. Must start with a letter or `_` (an underscore) followed by letters, digits, or `_`.\n",
"1. Must not be a [keyword](https://docs.python.org/3.7/reference/lexical_analysis.html#keywords) (identifier reserved by Python):"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"source": [
"False await else import pass\n",
"None break except in raise\n",
"True class finally is return\n",
"and continue for lambda try\n",
"as def from nonlocal while\n",
"assert del global not with\n",
"async elif if or yield"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"**Exercise** Evaluate the following cell and check if any of the rules above is violated."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T07:45:48.191750Z",
"start_time": "2020-09-04T07:45:48.134981Z"
},
"code_folding": [],
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "e9a17d9488ef4086809fd5a69909b637",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"interactive(children=(Dropdown(description='assignment', options=('a-number = 15', 'a_number = 15', '15 = 15',…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from ipywidgets import interact\n",
"\n",
"\n",
"@interact\n",
"def identifier_syntax(\n",
" assignment=[\n",
" \"a-number = 15\",\n",
" \"a_number = 15\",\n",
" \"15 = 15\",\n",
" \"_15 = 15\",\n",
" \"del = 15\",\n",
" \"Del = 15\",\n",
" \"type = print\",\n",
" \"print = type\",\n",
" \"input = print\",\n",
" ]\n",
"):\n",
" exec(assignment)\n",
" print(\"Ok.\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"nbgrader": {
"grade": true,
"grade_id": "invalid-identifiers",
"locked": false,
"points": 0,
"schema_version": 3,
"solution": true,
"task": false
},
"slideshow": {
"slide_type": "-"
}
},
"source": [
"1. `a-number = 15` violates Rule 1 because `-` is not allowed. `-` is interpreted as an operator.\n",
"1. `15 = 15` violates Rule 1 because `15` starts with a digit instead of letter or _.\n",
"1. `del = 15` violates Rule 2 because `del` is a keyword."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
},
"tags": []
},
"source": [
"What can we learn from the above examples?"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"- `del` is a keyword and `Del` is not because identifiers are case sensitive.\n",
"- Function/method/type names `print`/`input`/`type` are not keywords and can be reassigned. \n",
" This can useful if you want to modify the default implementations without changing their source code."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
},
"tags": []
},
"source": [
"To help make code more readable, additional style guides such as [PEP 8](https://www.python.org/dev/peps/pep-0008/#function-and-variable-names) are available:"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"source": [
"- Function names should be lowercase, with words separated by underscores as necessary to improve readability. \n",
"- Variable names follow the same convention as function names."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"## User Input"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"**How to let the user input a value at *runtime*, \n",
"i.e., as the program executes?**"
]
},
{
"cell_type": "markdown",
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-03T00:36:13.424771Z",
"start_time": "2020-09-03T00:36:13.418453Z"
},
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"We can use the method `input`:\n",
"- There is no need to delimit the input string by quotation marks.\n",
"- Simply press `enter` after typing a string."
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T06:16:10.739529Z",
"start_time": "2020-09-04T06:16:07.981984Z"
},
"slideshow": {
"slide_type": "-"
},
"tags": [
"remove-output"
]
},
"outputs": [
{
"name": "stdin",
"output_type": "stream",
"text": [
"Please input your name: CHAN, Chung\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Your name is CHAN, Chung\n"
]
}
],
"source": [
"print('Your name is', input('Please input your name: '))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"- The `input` method prints its argument, if any, as a [prompt](https://en.wikipedia.org/wiki/Command-line_interface#Command_prompt). \n",
"- It takes user's input and *returns* it as a string. `print` takes in the string and prints it."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**Exercise** Explain whether the following code prints `'My name is Python'`. Does `print` return a value? "
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T06:16:58.364342Z",
"start_time": "2020-09-04T06:16:58.357032Z"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Python\n",
"My name is None\n"
]
}
],
"source": [
"print('My name is', print('Python'))"
]
},
{
"cell_type": "markdown",
"metadata": {
"nbgrader": {
"grade": true,
"grade_id": "print-returns-none",
"locked": false,
"points": 0,
"schema_version": 3,
"solution": true,
"task": false
},
"slideshow": {
"slide_type": "-"
}
},
"source": [
"- Unlike `input`, the function `print` does not return the string it is trying to print. Printing a string is, therefore, different from returning a string.\n",
"- `print` actually returns a `None` object that gets printed as `None`."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Type Conversion"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"The following program tries to compute the sum of two numbers from user inputs:"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T06:17:10.204755Z",
"start_time": "2020-09-04T06:17:06.438645Z"
},
"slideshow": {
"slide_type": "-"
},
"tags": [
"remove-output"
]
},
"outputs": [
{
"name": "stdin",
"output_type": "stream",
"text": [
"Please input an integer: 1\n",
"Please input another integer: 2\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 + 2 is equal to 12\n"
]
}
],
"source": [
"num1 = input('Please input an integer: ')\n",
"num2 = input('Please input another integer: ')\n",
"print(num1, '+', num2, 'is equal to', num1 + num2)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"**Exercise** There is a [bug](https://en.wikipedia.org/wiki/Software_bug) in the above code. Can you locate the error?"
]
},
{
"cell_type": "markdown",
"metadata": {
"nbgrader": {
"grade": true,
"grade_id": "cell-d1d22bc89eb9f7b6",
"locked": false,
"points": 0,
"schema_version": 3,
"solution": true,
"task": false
},
"slideshow": {
"slide_type": "-"
}
},
"source": [
"The two numbers are concatenated instead of added together."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"`input` *returns* user input as a string. \n",
"E.g., if the user enters `12`, the input is\n",
"- not treated as the integer twelve, but rather\n",
"- treated as a string containing two characters, one followed by two."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"To see this, we can use `type` to return the data type of an expression."
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T06:17:27.250633Z",
"start_time": "2020-09-04T06:17:22.253068Z"
},
"slideshow": {
"slide_type": "-"
},
"tags": [
"remove-output"
]
},
"outputs": [
{
"name": "stdin",
"output_type": "stream",
"text": [
"Please input an integer: 1\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Your input is 1 with type \n"
]
}
],
"source": [
"num1 = input('Please input an integer: ')\n",
"print('Your input is', num1, 'with type', type(num1))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**Exercise** `type` applies to any expressions. Try it out below on `15`, `print`, `print()`, `input`, and even `type` itself and `type(type)`."
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T06:17:39.062596Z",
"start_time": "2020-09-04T06:17:39.051304Z"
},
"nbgrader": {
"grade": true,
"grade_id": "type",
"locked": false,
"points": 0,
"schema_version": 3,
"solution": true,
"task": false
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n"
]
},
{
"data": {
"text/plain": [
"(int, builtin_function_or_method, NoneType, method, type, type)"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"type(15), type(print), type(print()), type(input), type(type), type(type(type))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**So what happens when we add strings together?**"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T06:17:49.789649Z",
"start_time": "2020-09-04T06:17:49.781630Z"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/plain": [
"'456'"
]
},
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"'4' + '5' + '6'"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"**How to fix the bug then?**"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"We can convert a string to an integer using `int`."
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T06:18:27.244226Z",
"start_time": "2020-09-04T06:18:27.236901Z"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/plain": [
"15"
]
},
"execution_count": 33,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"int('4') + int('5') + int('6')"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"We can also convert an integer to a string using `str`."
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T06:18:45.050543Z",
"start_time": "2020-09-04T06:18:45.044301Z"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/plain": [
"'456'"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"str(4) + str(5) + str(6)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**Exercise** Fix the bug in the following cell."
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T06:19:05.685119Z",
"start_time": "2020-09-04T06:18:54.936526Z"
},
"nbgrader": {
"grade": false,
"grade_id": "string-concat-bug",
"locked": false,
"schema_version": 3,
"solution": true,
"task": false
},
"slideshow": {
"slide_type": "-"
},
"tags": [
"remove-output"
]
},
"outputs": [
{
"name": "stdin",
"output_type": "stream",
"text": [
"Please input an integer: 1\n",
"Please input another integer: 2\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 + 2 is equal to 3\n"
]
}
],
"source": [
"num1 = input('Please input an integer: ')\n",
"num2 = input('Please input another integer: ')\n",
"# print(num1, '+', num2, 'is equal to', num1 + num2) # fix this line below\n",
"### BEGIN SOLUTION\n",
"print(num1, '+', num2, 'is equal to', int(num1) + int(num2))\n",
"### END SOLUTION"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Error"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"In addition to writing code, a programmer spends significant time in *debugging* code that contains errors.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"**Can an error be automatically detected by the computer?**"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"- You have just seen an example of *logical error*, which is due to an error in the logic. \n",
"- The ability to debug or even detect such error is, unfortunately, beyond Python's intelligence."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Other kinds of error may be detected automatically. \n",
"As an example, note that we can omit `+` for string concatenation, but we cannot omit it for integer summation:"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T06:19:19.006999Z",
"start_time": "2020-09-04T06:19:18.997817Z"
},
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Skipping + for string concatenation\n"
]
},
{
"data": {
"text/plain": [
"'456'"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"print('Skipping + for string concatenation')\n",
"'4' '5' '6'"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T06:19:20.450012Z",
"start_time": "2020-09-04T06:19:20.443547Z"
},
"scrolled": true,
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"ename": "SyntaxError",
"evalue": "invalid syntax (, line 2)",
"output_type": "error",
"traceback": [
"\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m2\u001b[0m\n\u001b[0;31m 4 5 6\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
]
}
],
"source": [
"print('Skipping + for integer summation')\n",
"4 5 6"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Python interpreter detects the bug and raises a *syntax* error."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**Why Syntax error can be detected automatically? \n",
"Why is the print statement before the error not executed?**"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"- The Python interpreter can detect syntax error even before executing the code because\n",
"- the interpreter simply fails translates the code to lower-level executable code."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"The following code raises a different kind of error."
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T06:19:36.771874Z",
"start_time": "2020-09-04T06:19:36.753536Z"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Evaluating '4' + '5' + 6\n"
]
},
{
"ename": "TypeError",
"evalue": "can only concatenate str (not \"int\") to str",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Evaluating '4' + '5' + 6\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;34m'4'\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m'5'\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m6\u001b[0m \u001b[0;31m# summing string with integer\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m: can only concatenate str (not \"int\") to str"
]
}
],
"source": [
"print(\"Evaluating '4' + '5' + 6\")\n",
"'4' + '5' + 6 # summing string with integer"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"**Why Python throws a TypeError when evaluating `'4' + '5' + 6`?**"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"There is no default implementation of `+` operation on a value of type `str` and a value of type `int`. "
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"- Unlike the syntax error, the Python interpreter can only detect a type error at runtime (when executing the code.) \n",
"- Hence, such an error is called a *runtime error*.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**Why is TypeError a runtime error?**"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
" The short answer is that Python is a [strongly-and-dynamically-typed](https://en.wikipedia.org/wiki/Strong_and_weak_typing) language:\n",
"- Strongly-typed: Python does not force a type conversion to avoid a type error.\n",
"- Dynamically-typed: Python checks data type only at runtime after translating the code to machine code."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
},
"tags": []
},
"source": [
"The underlying details are more complicated than required for this course. It helps if you already know the following languages:\n",
"- JavaScript, which is a *weakly-typed* language that forces a type conversion to avoid a type error.\n",
"- C, which is a *statically-typed* language that checks data type during compilation."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T06:19:54.842114Z",
"start_time": "2020-09-04T06:19:54.833509Z"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"application/javascript": [
"element.append('4' + '5' + 6) // no error because 6 is converted to a str automatically\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%javascript\n",
"element.append('4' + '5' + 6) // no error because 6 is converted to a str automatically"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"A weakly-typed language may seem more robust, but it can lead to [more logical errors](https://www.oreilly.com/library/view/fluent-conference-javascript/9781449339203/oreillyvideos1220106.html).\n",
"\n",
"- JavaScript is [tricky](https://github.com/denysdovhan/wtfjs).\n",
"- To improve readability and avoid logical errors, [typescript](https://www.typescriptlang.org/) is a strongly-typed replacement of javascript.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**Exercise** Not all the strings can be converted into integers. Try breaking the following code by providing invalid inputs and record them in the subsequent cell. Explain whether the errors are runtime errors."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T06:20:16.984476Z",
"start_time": "2020-09-04T06:20:10.601798Z"
},
"slideshow": {
"slide_type": "-"
},
"tags": [
"remove-output"
]
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Please input an integer: 1\n",
"Please input another integer: two\n"
]
},
{
"ename": "ValueError",
"evalue": "invalid literal for int() with base 10: 'two'",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mnum1\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0minput\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Please input an integer: '\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mnum2\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0minput\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Please input another integer: '\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnum1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'+'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnum2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'is equal to'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnum1\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnum2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mValueError\u001b[0m: invalid literal for int() with base 10: 'two'"
]
}
],
"source": [
"num1 = input('Please input an integer: ')\n",
"num2 = input('Please input another integer: ')\n",
"print(num1, '+', num2, 'is equal to', int(num1) + int(num2))"
]
},
{
"cell_type": "markdown",
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-03T00:03:42.085828Z",
"start_time": "2020-09-03T00:03:42.073895Z"
},
"nbgrader": {
"grade": true,
"grade_id": "invalid-input",
"locked": false,
"points": 0,
"schema_version": 3,
"solution": true,
"task": false
},
"slideshow": {
"slide_type": "-"
}
},
"source": [
"The possible invalid inputs are:\n",
"> `4 + 5 + 6`, `15.0`, `fifteen`\n",
"\n",
"It raises a value error, which is a runtime error detected during execution. \n",
"\n",
"Note that the followings are okay\n",
"> int('-1'), eval('4 + 5 + 6')"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Floating Point Numbers"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Not all numbers are integers. In Enginnering, we often need to use fractions."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**How to enter fractions in a program?**"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T06:22:42.771953Z",
"start_time": "2020-09-04T06:22:42.764077Z"
},
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"(-0.1, -0.1, -0.1, float, float, float)"
]
},
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x = -0.1 # decimal number\n",
"y = -1.0e-1 # scientific notation\n",
"z = -1 / 10 # fraction\n",
"x, y, z, type(x), type(y), type(z)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**What is the type `float`?**"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"- `float` corresponds to the [*floating point* representation](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Floating-point_numbers). \n",
"- A `float` in stored exactly the way we write it in scientific notation: \n",
"\n",
"$$\n",
"\\overbrace{-}^{\\text{sign}} \\underbrace{1.0}_{\\text{mantissa}\\kern-1em}e\\overbrace{-1}^{\\text{exponent}\\kern-1em}=-1\\times 10^{-1}\n",
"$$\n",
"- An efficient implementation is more complicated. Try the [IEEE-754 Floating Point Converter](https://www.h-schmidt.net/FloatConverter/IEEE754.html)."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Integers in mathematics may be regarded as a `float` instead of `int`:"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T06:24:54.046251Z",
"start_time": "2020-09-04T06:24:54.038091Z"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/plain": [
"(float, float)"
]
},
"execution_count": 43,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"type(1.0), type(1e2)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"You can also convert an `int` or a `str` to a `float`."
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T06:24:55.743628Z",
"start_time": "2020-09-04T06:24:55.736352Z"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/plain": [
"(1.0, 1.0)"
]
},
"execution_count": 44,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"float(1), float('1')"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**Is it better to store an integer as `float`?**"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Python stores a [floating point](https://docs.python.org/3/library/sys.html#sys.float_info) with finite precision (usually as a 64bit binary fraction):"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T06:24:59.506258Z",
"start_time": "2020-09-04T06:24:59.498308Z"
},
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1)"
]
},
"execution_count": 45,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import sys\n",
"\n",
"sys.float_info"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
},
"tags": []
},
"source": [
"It cannot represent a number larger than the `max`:"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T06:25:01.090577Z",
"start_time": "2020-09-04T06:25:01.084045Z"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/plain": [
"inf"
]
},
"execution_count": 46,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sys.float_info.max * 2"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
},
"tags": []
},
"source": [
"The precision also affects the check for equality."
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-08T00:06:41.090541Z",
"start_time": "2020-09-08T00:06:41.074137Z"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/plain": [
"(True, False, True)"
]
},
"execution_count": 47,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"(\n",
" 1.0 == 1.0 + sys.float_info.epsilon * 0.5, # returns true if equal\n",
" 1.0 == 1.0 + sys.float_info.epsilon * 0.6,\n",
" sys.float_info.max + 1 == sys.float_info.max,\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Another issue with float is that it may keep more decimal places than desired."
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T06:25:05.456795Z",
"start_time": "2020-09-04T06:25:05.449284Z"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/plain": [
"0.3333333333333333"
]
},
"execution_count": 48,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"1/3"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**How to [round](https://docs.python.org/3/library/functions.html#round) a floating point number to the desired number of decimal places?**"
]
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T06:25:11.466342Z",
"start_time": "2020-09-04T06:25:11.458247Z"
},
"scrolled": true,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"(2.67, 2.67)"
]
},
"execution_count": 50,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"round(2.665, 2), round(2.675, 2)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"**Why 2.675 rounds to 2.67 instead of 2.68?**"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"- A `float` is actually represented in binary. \n",
"- A decimal fraction [may not be represented exactly in binary](https://docs.python.org/3/tutorial/floatingpoint.html#tut-fp-issues)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Exercise** Use the [IEEE-754 Floating Point Converter](https://www.h-schmidt.net/FloatConverter/IEEE754.html) to find out the value actually stored in float for 2.675."
]
},
{
"cell_type": "markdown",
"metadata": {
"nbgrader": {
"grade": true,
"grade_id": "precision-round",
"locked": false,
"points": 0,
"schema_version": 3,
"solution": true,
"task": false
}
},
"source": [
"The value stored is `2.6749999523162841796875`, which explains why it is rounded to `2.67` instead of `2.68`."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"The `round` function can also be applied to an integer."
]
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T06:25:18.702100Z",
"start_time": "2020-09-04T06:25:18.695978Z"
},
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"(200, 200)"
]
},
"execution_count": 51,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"round(150, -2), round(250, -2)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"**Why 250 rounds to 200 instead of 300?**"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"- Python 3 implements the default rounding method in [IEEE 754](https://en.wikipedia.org/w/index.php?title=IEEE_754#Rounding_rules)."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## String Formatting"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**Can we round a `float` or `int` for printing but not calculation?**"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"This is possible with format strings:"
]
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T06:25:27.998736Z",
"start_time": "2020-09-04T06:25:27.991428Z"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"x ≈ 3333.33 (rounded to 2 decimal places)\n"
]
},
{
"data": {
"text/plain": [
"3333.3333333333335"
]
},
"execution_count": 52,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x = 10000/3\n",
"print('x ≈ {:.2f} (rounded to 2 decimal places)'.format(x))\n",
"x"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"- `{:.2f}` is a [*replacement field*][repf]/place holder \n",
"- that gets replaced by a string \n",
"- that represents the argument `x` of `format` \n",
"- according to the [format specification][fspec] `.2f`, i.e., \n",
" a decimal floating point number rounded to 2 decimal places.\n",
" \n",
"[repf]: https://docs.python.org/3/library/string.html#format-string-syntax\n",
"[fspec]: https://docs.python.org/3/library/string.html#format-specification-mini-language"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**Exercise** Play with the following widget to learn the effect of different format specifications. In particular, print `10000/3` as `3,333.33`."
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T09:30:51.495136Z",
"start_time": "2020-09-04T09:30:51.404289Z"
},
"code_folding": [
7
],
"scrolled": true,
"slideshow": {
"slide_type": "-"
},
"tags": []
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "94d0295a09024a3fb70b734036b25da3",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"interactive(children=(Text(value='10000/3', description='x'), Dropdown(description='sign', options={'None': ''…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from ipywidgets import interact\n",
"\n",
"\n",
"@interact(\n",
" x=\"10000/3\",\n",
" align={\"None\": \"\", \"<\": \"<\", \">\": \">\", \"=\": \"=\", \"^\": \"^\"},\n",
" sign={\"None\": \"\", \"+\": \"+\", \"-\": \"-\", \"SPACE\": \" \"},\n",
" width=(0, 20),\n",
" grouping={\"None\": \"\", \"_\": \"_\", \",\": \",\"},\n",
" precision=(0, 20),\n",
")\n",
"def print_float(x, sign, align, grouping, width=0, precision=2):\n",
" format_spec = (\n",
" f\"{{:{align}{sign}{'' if width==0 else width}{grouping}.{precision}f}}\"\n",
" )\n",
" print(\"Format spec:\", format_spec)\n",
" print(\"x ≈\", format_spec.format(eval(x)))"
]
},
{
"cell_type": "code",
"execution_count": 54,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T09:31:41.706086Z",
"start_time": "2020-09-04T09:31:41.699822Z"
},
"nbgrader": {
"grade": true,
"grade_id": "format-spec",
"locked": false,
"points": 0,
"schema_version": 3,
"solution": true,
"task": false
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"3,333.33\n"
]
}
],
"source": [
"print('{:,.2f}'.format(10000/3))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"String formatting is useful for different data types other than `float`. \n",
"E.g., consider the following program that prints a time specified by some variables."
]
},
{
"cell_type": "code",
"execution_count": 55,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-03T16:19:12.214797Z",
"start_time": "2020-09-03T16:19:12.206882Z"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The time is 12:34:56.\n"
]
}
],
"source": [
"# Some specified time\n",
"hour = 12\n",
"minute = 34\n",
"second = 56\n",
"\n",
"print(\"The time is \" + str(hour) + \":\" + str(minute) + \":\" + str(second)+\".\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Imagine you have to show also the date in different formats. \n",
"The code can become very hard to read/write because \n",
"- the message is a concatenation of multiple strings and\n",
"- the integer variables need to be converted to strings."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Omitting `+` leads to syntax error. Removing `str` as follows also does not give the desired format."
]
},
{
"cell_type": "code",
"execution_count": 56,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-03T01:34:10.916259Z",
"start_time": "2020-09-03T01:34:10.909394Z"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The time is 12 : 34 : 56 .\n"
]
}
],
"source": [
"print(\"The time is \", hour, \":\", minute, \":\", second, \".\") # note the extra spaces"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"To make the code more readable, we can use the `format` function as follows."
]
},
{
"cell_type": "code",
"execution_count": 57,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T06:25:48.245398Z",
"start_time": "2020-09-04T06:25:48.229809Z"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The time is 12:34:56.\n"
]
}
],
"source": [
"message = \"The time is {}:{}:{}.\"\n",
"print(message.format(hour, minute, second))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"- We can have multiple *place-holders* `{}` inside a string.\n",
"- We can then provide the contents (any type: numbers, strings..) using the `format` function, which\n",
"- substitutes the place-holders by the function arguments from left to right."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"According to the [string formatting syntax](https://docs.python.org/3/library/string.html#format-string-syntax), we can change the order of substitution using \n",
"- indices *(0 is the first item)* or \n",
"- names inside the placeholder `{}`:"
]
},
{
"cell_type": "code",
"execution_count": 58,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T06:59:48.333999Z",
"start_time": "2020-09-04T06:59:48.328303Z"
},
"scrolled": true,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"You should do only what I say instead of what I do.\n",
"The surname of John Doe is Doe.\n"
]
}
],
"source": [
"print(\"You should {0} {1} what I say instead of what I {0}.\".format(\"do\", \"only\"))\n",
"print(\"The surname of {first} {last} is {last}.\".format(first=\"John\", last=\"Doe\"))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"You can even put variables inside the format specification directly and have a nested string formatting."
]
},
{
"cell_type": "code",
"execution_count": 59,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T06:25:54.529244Z",
"start_time": "2020-09-04T06:25:54.522113Z"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"3333.3333333333335\n"
]
}
],
"source": [
"align, width = \"^\", 5\n",
"print(f\"{{:*{align}{width}}}\".format(x)) # note the syntax f\"...\""
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
},
"tags": []
},
"source": [
"In the above, `f\"...\"` is special syntax for [formatted string](https://docs.python.org/3/library/string.html#format-string-syntax)."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**Exercise** Play with the following widget to learn more about the formating specification. \n",
"1. What happens when `align` is none but `fill` is `*`?\n",
"1. What happens when the `expression` is a multi-line string?"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T09:18:34.925753Z",
"start_time": "2020-09-04T09:18:34.858335Z"
},
"code_folding": [],
"scrolled": true,
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "08402a2d291348b98dc754d40ed043d7",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"interactive(children=(Text(value=\"'ABC'\", description='expression'), Text(value='*', description='fill'), Drop…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from ipywidgets import interact\n",
"\n",
"\n",
"@interact(\n",
" expression=r\"'ABC'\",\n",
" fill=\"*\",\n",
" align={\"None\": \"\", \"<\": \"<\", \">\": \">\", \"=\": \"=\", \"^\": \"^\"},\n",
" width=(0, 20),\n",
")\n",
"def print_objectt(expression, fill, align=\"^\", width=10):\n",
" format_spec = f\"{{:{fill}{align}{'' if width==0 else width}}}\"\n",
" print(\"Format spec:\", format_spec)\n",
" print(\"Print:\", format_spec.format(eval(expression)))"
]
},
{
"cell_type": "markdown",
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-04T09:16:52.179558Z",
"start_time": "2020-09-04T09:16:52.172995Z"
},
"nbgrader": {
"grade": true,
"grade_id": "string-formatting",
"locked": false,
"points": 0,
"schema_version": 3,
"solution": true,
"task": false
}
},
"source": [
"1. It returns a ValueError because align must be specified when fill is.\n",
"1. The newline character is simply regarded a character. The formatting is not applied line-by-line. E.g., try 'ABC\\nDEF'."
]
}
],
"metadata": {
"celltoolbar": "Create Assignment",
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.8"
},
"latex_envs": {
"LaTeX_envs_menu_present": true,
"autoclose": false,
"autocomplete": true,
"bibliofile": "biblio.bib",
"cite_by": "apalike",
"current_citInitial": 1,
"eqLabelWithNumbers": true,
"eqNumInitial": 1,
"hotkeys": {
"equation": "Ctrl-E",
"itemize": "Ctrl-I"
},
"labels_anchors": false,
"latex_user_defs": false,
"report_style_numbering": false,
"user_envs_cfg": false
},
"rise": {
"enable_chalkboard": true,
"scroll": true,
"theme": "white"
},
"toc": {
"base_numbering": 1,
"nav_menu": {
"height": "195px",
"width": "330px"
},
"number_sections": true,
"sideBar": true,
"skip_h1_title": true,
"title_cell": "Table of Contents",
"title_sidebar": "Contents",
"toc_cell": false,
"toc_position": {
"height": "454.418px",
"left": "1533px",
"top": "110.284px",
"width": "435.327px"
},
"toc_section_display": true,
"toc_window_display": false
},
"widgets": {
"application/vnd.jupyter.widget-state+json": {
"state": {},
"version_major": 2,
"version_minor": 0
}
}
},
"nbformat": 4,
"nbformat_minor": 4
}